import UIKit

var str = "Hello, playground"

//在类的构造方法中，编译器会进行4项安全性检查：
//检查1：子类的指定构造方法中，必须完成当前类所有存储属性的构造，才能调用父类的指定构造方法。此检查可以保证：在构造完从父类继承下来的所有存储属性前，本身定义的所有存储属性也已构造完成。
//检查2：子类如果要自定义父类中存储属性的值，必须在调用父类的构造方法之后进行设置。此检查可以保证：子类在设置从父类继承下来的存储属性时，此属性已构造完成。
//检查3：如果便利构造方法中需要重新设置某些存储属性的值，必须在调用指定构造方法之后进行设置。此检查可以保证：便利构造方法中对存储属性值的设置不会被指定构造方法中的设置覆盖。·
//检查4：子类在调用父类构造方法之前，不能使用self来引用属性（基类无所谓）。此检查可以保证在使用self关键字调用实例本身时，实例已经构造完成。

class SuperClass {
    var property:Int
    init(param:Int) {
        property = param
    }
    
    deinit {
        print("父类销毁")
    }
}

class SubClass:SuperClass {
    var subProperty:Int
    init() {
        //必须在调用父类指定构造方法前,完成本身属性的赋值
        subProperty = 1
        super.init(param: 0)
        
        //如果子类要重新赋值父类继承来的属性,必须在调用父类指定构造方法之后
        property = 2
        
        //在完成父类的构造方法之后,才能使用self关键字
        self.subProperty = 3
    }
    
    convenience init(param: Int,param2:Int) {
        self.init()
        
        //便利构造方法中要修改属性的值碧玺在调用指定构造犯法之后
        subProperty = param
        property = param2
    }
    
    deinit {
        print("子类销毁")
    }
}

var sub:SubClass? = SubClass()
sub = nil

